
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;
using System.Diagnostics;
using System.Web;

using Swaf;
using Swaf.Call;


namespace Swaf.BizRule
{
	/// <summary>
	/// Summary description for CallRulesBizRule.
	/// </summary>
	internal class CallRulesBizRule
	{
		public static IResults execute(IApplication app, IRuleContext context, string callInfo)
		{
			IList calls = processCallInfo(callInfo);
			if(calls.Count > 1)
			{
				string[] ruleNames = new string[calls.Count];
				object[] ruleParams = new object[calls.Count];
				int pos = 0;
				foreach(CallInfo theCall in calls)
				{
					ruleNames[pos] = theCall.RuleName;
					ruleParams[pos] = Serialization.deserialize(theCall.ParamType, theCall.RuleParam);
				}
				return app.ruleMgr.execute(ruleNames, ruleParams);
			}
			else if(calls.Count == 1)
			{
				CallInfo theCall = (CallInfo)calls[0];
				return app.ruleMgr.execute(theCall.RuleName, Serialization.deserialize(theCall.ParamType, theCall.RuleParam));
			}
			else
				throw new Exception(String.Format("No rules were specified to be called.  Make sure the callInfo is formated in the proper format.  callInfo given was: {0}", callInfo));
		}

		public IResults executeBizRules(IApplication app, IRuleContext context, string callInfo)
		{
			return execute(app, context, callInfo);
		}

		/// <summary>
		/// This is the main logic that takes a formatted string of rule calls and parses it for easy
		/// calls to ruleMgr.execute.
		/// </summary>
		/// <remarks>This methods currently only accepts a name/value pair formatted in the W3C Form Data Set standard.
		/// <a href="http://www.w3.org/MarkUp/html-spec/html-spec_8.html">Here</a></remarks>
		/// <param name="callInfo"></param>
		/// <returns></returns>
		static private IList processCallInfo(string callInfo)
		{
			IList callList = new ArrayList();
			if (callInfo.StartsWith(MessagingRuleMgrCall.RuleMessageIdentifier))
				callInfo=callInfo.Replace(MessagingRuleMgrCall.RuleMessageIdentifier,"");

			string[] pairs = callInfo.Split('&');

			CallInfo currentCall = new CallInfo(null,null,null);
			bool gotName = false;
			int numPairs = pairs.Length;
			for(int x = 0; x < numPairs; ++x)
			{
				string[] info = processPair(pairs[x]);
				if(String.Compare(info[0], "rulename",true) == 0)
				{
					if(gotName)
					{
						currentCall = new CallInfo(HttpUtility.HtmlDecode(info[1]), null,null);
					}
					else
					{
						currentCall.RuleName = info[1];
						gotName = true;
					}
					callList.Add(currentCall);
				}
				else if(String.Compare(info[0], "param",true) == 0)
					currentCall.RuleParam = HttpUtility.HtmlDecode(info[1]);
				else if(String.Compare(info[0], "paramtype",true) == 0)
					currentCall.ParamType = HttpUtility.HtmlDecode(info[1]);

			}

			return callList;
		}

		static private string[] processPair(string pair)
		{
			int pos = pair.IndexOf('=');
			if(pos == -1)
				throw new Exception(String.Format("Bad format of callInfo.  Must contain name/value pairs.  One pair doesn't contain an =: {0}", pair));
			return new string[]{pair.Substring(0, pos), pair.Substring(pos +1)};
		}

		private class CallInfo
		{
			public string RuleName;
			public string RuleParam;
			public string ParamType;

			public CallInfo(string ruleName, string ruleParam, string paramType)
			{
				RuleName = ruleName;
				RuleParam = ruleParam;
				ParamType = paramType;
			}
		}
	}
}
